<?php
/**
 * Note: *
 */
namespace App\Services;

use Illuminate\Support\Str;

class IpAddrService
{
    public const ACTION_LOGIN = 0;
    public const ACTION_LOGIN_ADMIN = 1;
    public const ACTION_REG = 2;

    private static $ip2region;

    private static function getRegion()
    {
        if (self::$ip2region) return self::$ip2region;
        self::$ip2region = new \Ip2Region();
        return self::$ip2region;
    }

    /**
     * 查询
     * @param string $ip
     * @return array|false
     */
    public static function query(string $ip)
    {
        $ip2region = self::getRegion();
        try {
            $res = $ip2region->btreeSearch($ip);
        } catch (\Exception $e) {
            info(__METHOD__, [$e->getMessage()]);
            return false;
        }
        // 未找到归属地信息 记录IP
        if (!$res || empty($res['region'])) {
            info(__METHOD__, ['未找到IP归属地信息', $ip, $res]);
            return false;
        }
        list($country, $cityId, $province, $city, $network) = explode('|', $res['region']);
        return [$province, $city];
    }

    /**
     * @param string $ip
     * @return string
     */
    public static function queryString(string $ip): string
    {
        $ip2region = self::getRegion();
        try {
            $res = $ip2region->btreeSearch($ip);
        } catch (\Exception $e) {
            info(__METHOD__, [$e->getMessage()]);
            return false;
        }
        // 未找到归属地信息 记录IP
        if (!$res || empty($res['region'])) {
            info(__METHOD__, ['未找到IP归属地信息', $ip, $res]);
            return false;
        }
        return $res['region'];
    }

    /**
     * 使用本地服务
     * @param string $ip
     * @param int $action
     * @return bool|int|void
     */
    public static function isWarningLocal(string $ip, int $action = self::ACTION_REG)
    {
        if (!$region = self::queryString($ip)) return false;

        // 区分注册事件和登录事件
        if ($action === self::ACTION_REG) {
            return Str::contains($region, '广西');
        } else if ($action === self::ACTION_LOGIN) {
            return Str::contains($region, '广西');
        } else if ($action === self::ACTION_LOGIN_ADMIN) {
            $allowRegions = ['上海', '杭州', '金华', '美国', '昆山'];
            return !Str::contains($region, $allowRegions);
        }
    }

    /**
     * 先使用接口查询， 如果出错使用本地服务
     * @param string $ip
     * @param int $action
     * @return bool|void
     */
    public static function isWarning(string $ip, int $action = self::ACTION_REG)
    {
        $response = false;
        $err = false;
        try {
            $response = Ip138Service::isWarning($ip, $action);
        } catch (\Exception $exception) {
            info(__METHOD__, [$exception->getMessage()]);
            $err = true;
        }

        if (!$err) return $response;
        return self::isWarningLocal($ip, $action);
    }
}
